package cn.tedu.stream;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("B","A","D","C","E","10","20","30");
        List<Student> listStudent = Arrays.asList(
                new Student(1,"吉祥1",80,"A班"),
                new Student(5,"吉祥2",50,"A班"),
                new Student(2,"吉祥3",70,"B班"),
                new Student(3,"吉祥4",90,"C班"),
                new Student(6,"吉祥5",80,"C班"),
                new Student(4,"吉祥6",30,"D班")
        );

       //  foreach 遍历
        list.stream().forEach(s-> System.out.println(s));
        // 最终可以简化
        list.forEach(System.out::println);
        System.out.println("---------------分割线-------");

        // filter过滤    返回集合.collect(Collectors.toList())
        List<String> collect = list.stream().filter(s -> s.length() > 1).collect(Collectors.toList());
        collect.forEach(System.out::println);
        System.out.println("---------------分割线-------");

        // collect(Collector c) -----> 收集（终结方法）  把流返回list集合
        List<String> collect5 = list.stream().collect(Collectors.toList());

        // map 如果需要把流中的元素返回到另一个流  ::  中间增加了匹配数字
        Stream<Integer> integerStream1 = list.stream().filter(s->s.matches("\\d+")).map(s->Integer.parseInt(s));
        // 最终简化
        Stream<Integer> integerStream = list.stream().filter(s->s.matches("\\d+")).map(Integer::parseInt);


        // count（终结方法） -统计个数
        long count = list.stream().count();

        // limit 取用前面几个
        list.stream().limit(3).forEach(System.out::println);

        // skip 跳过前面几个
        list.stream().skip(3).forEach(System.out::println);

        // Stream.concat(streamA,streamB) 合并两个流结果
        List<? extends Serializable> collect2 = Stream.concat(list.stream(), integerStream1).collect(Collectors.toList());
        collect2.forEach(System.out::println);

        // distinct 去重
        List<String> collect3 = list.stream().distinct().collect(Collectors.toList());
        collect3.forEach(System.out::println);

        // sorted 排序 默认升序  sorted(Comparator.reverseOrder()) 反转顺序 也就是倒序
        List<String> collect4 = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        collect4.forEach(System.out::println);


        // 是否全部匹配allMatch，是否至少匹配一个anyMatch，是否没有匹配的noneMatch
        boolean b = list.stream().allMatch(s -> s.contains("1"));


        //  聚合函数
        //mapToInt 转换为数字流 .sum()求和
        int sum = list.stream().filter(s -> s.matches("\\d+")).mapToInt(s -> Integer.parseInt(s)).sum();

        // .average()求平均数
        OptionalDouble average = list.stream().filter(s -> s.matches("\\d+")).mapToDouble(s -> Double.parseDouble(s)).average();
        double asDouble = average.getAsDouble();

        // .max()求最大值 最小值 .min()
        OptionalInt max = list.stream().filter(s -> s.matches("\\d+")).mapToInt(s -> Integer.parseInt(s)).max();
        int asInt = max.getAsInt();


        //扩展
        // Collectors.groupingBy分组按照平均分升序返回map
        LinkedHashMap<String, Double> collect1 = listStudent.stream().collect(Collectors.groupingBy(
                Student::getClassName,
                //需要顺序就用linkedHashMap 默认是hashMap
                LinkedHashMap::new,
                Collectors.averagingInt(Student::getScore)
        ));
        // 根据分组把map排序
        Set<Map.Entry<String, Double>> entries = collect1.entrySet();
        LinkedHashMap<String, Double> collect6 = entries.stream().sorted(Map.Entry.<String, Double>comparingByValue().reversed()).collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldVal, newVal) -> oldVal,
                LinkedHashMap::new
        ));
        System.out.println(collect6);
    }
}
